home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / WIN_PRO / DS-1.ZIP;1 / PREPROC.ZIP / P_INIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-10  |  21.0 KB  |  676 lines

  1. /*
  2.  * This file contains functions used to initialize the preprocessor,
  3.  *  particularly those for establishing implementation-dependent standard
  4.  *  macro definitions.
  5.  */
  6. #include "../preproc/preproc.h"
  7.  
  8. /*
  9.  * The following code is operating-system dependent [@p_init.01]. 
  10.  *  #includes and #defines.
  11.  */
  12.  
  13. #if PORT
  14.    /* something may be needed */
  15. Deliberate Syntax Error
  16. #endif                    /* PORT */
  17.  
  18. #if AMIGA || ATARI_ST || MACINTOSH || VM || MVS 
  19.    /* something may be needed */
  20. Deliberate Syntax Error
  21. #endif                    /* AMIGA || ATARI_ST || ... */
  22.  
  23. #if MSDOS
  24. #if MICROSOFT || HIGHC_386 || INTEL_386 || ZTC_386
  25.    /* nothing is needed */
  26. #endif                    /* MICROSOFT || HIGHC_386 || ... */
  27. #if TURBO
  28. #include <dir.h>
  29. #define Strng(s) #s
  30. #define StrMBody(m) Strng(m)
  31. #define CBufSz 200
  32. #endif                     /* TURBO */
  33. #endif                    /* MSDOS */
  34.  
  35. #if UNIX || VMS
  36.    /* nothing is needed */
  37. #endif                    /* UNIX || VMS */
  38.  
  39. /*
  40.  * End of operating-system specific code.
  41.  */
  42.  
  43. #include "../preproc/pproto.h"
  44.  
  45. /*
  46.  * Prototypes for static functions.
  47.  */
  48. hidden novalue define_opt   Params((char *s, int len, struct token *dflt));
  49. hidden novalue do_directive Params((char *s));
  50. hidden novalue mac_opts     Params((char *opt_lst, char **opt_args));
  51. hidden novalue undef_opt    Params((char *s, int len));
  52.  
  53. struct src dummy;
  54.  
  55. /*
  56.  * init_preproc - initialize all parts of the preprocessor, establishing
  57.  *  the primary file as the current source of tokens.
  58.  */
  59. novalue init_preproc(fname, opt_lst, opt_args)
  60. char *fname;
  61. char *opt_lst;
  62. char **opt_args;
  63.    {
  64.  
  65.    init_str();                      /* initialize string table */
  66.    init_tok();                      /* initialize tokenizer */
  67.    init_macro();                    /* initialize macro table */
  68.    init_files(opt_lst, opt_args);   /* initialize standard header locations */
  69.    dummy.flag = DummySrc;           /* marker at bottom of source stack */
  70.    dummy.ntoks = 0;
  71.    src_stack = &dummy;
  72.    mac_opts(opt_lst, opt_args);     /* process options for predefined macros */
  73.    source(fname);                   /* establish primary source file */
  74.    }
  75.  
  76. /*
  77.  * mac_opts - handle options which affect what predefined macros are in
  78.  *  effect when preprocessing starts. Some of these options may be system
  79.  *  specific. The options may be on the command line. On some systems they
  80.  *  may also be in environment variables or configurations files. Most
  81.  *  systems will have some predefined macros which are not dependent on
  82.  *  options; establish them also.
  83.  */
  84. static novalue mac_opts(opt_lst, opt_args)
  85. char *opt_lst;
  86. char **opt_args;
  87.    {
  88.    int i;
  89.  
  90. /*
  91.  * The following code is operating-system dependent [@p_init.02].
  92.  *  Establish predefined macros and look for options in environment
  93.  *  variables and/or configuration files that affect predefined macros.
  94.  */
  95.  
  96. #if PORT
  97.    /* something may be needed */
  98. Deliberate Syntax Error
  99. #endif                    /* PORT */
  100.  
  101. #if AMIGA || ATARI_ST || MACINTOSH || VM || MVS
  102.    /* something may be needed */
  103. Deliberate Syntax Error
  104. #endif                    /* AMIGA || ATARI_ST || ... */
  105.  
  106. #if MSDOS
  107. #if MICROSOFT
  108.    char *undef_model = "#undef M_I86SM\n#undef M_I86CM\n#undef M_I86MM\n"
  109.        "#undef M_I86LM\n#undef M_I86HM\n";
  110.    char *cl_var;
  111.    
  112.    do_directive("#define MSDOS 1\n");
  113.    do_directive("#define M_I86 1\n");
  114.    do_directive("#define M_I86SM 1\n");  /* small memory model */
  115.    
  116.    /*
  117.     * Process all applicable options from the CL environment variable.
  118.     */
  119.    cl_var = getenv("CL");
  120.    if (cl_var != NULL)
  121.       while (*cl_var != '\0') {
  122.          if (*cl_var == '/' || *cl_var == '-') {
  123.             ++cl_var;
  124.             switch (*cl_var) {
  125.                case 'U':
  126.                   /*
  127.                    * Undefine a specific identifier. Find the identifier 
  128.                    *  by skipping white space then locating its end.
  129.                    */
  130.                   ++cl_var;
  131.                   while (*cl_var == ' ' || *cl_var == '\t')
  132.                      ++cl_var;
  133.                   i = 0;
  134.                   while (cl_var[i] != ' ' && cl_var[i] != '\t' &&
  135.                     cl_var[i] != '\0')
  136.                      ++i;
  137.                   undef_opt(cl_var, i); /* undefine the identifier */
  138.                   cl_var += i;
  139.                   break;
  140.                case 'u':
  141.                   do_directive("#undef MSDOS\n");
  142.                   do_directive("#undef M_I86\n");
  143.                   do_directive("#undef NO_EXT_KEYS\n");
  144.                   do_directive("#undef _CHAR_UNSIGED\n"); 
  145.                   break;
  146.                case 'D':
  147.                   /*
  148.                    * Define an identifier. If no defining string is given
  149.                    *  define it to "1".
  150.                    */
  151.                   ++cl_var;
  152.                   while (*cl_var == ' ' || *cl_var == '\t')
  153.                      ++cl_var;
  154.                   i = 0;
  155.                   while (cl_var[i] != ' ' && cl_var[i] != '\t' &&
  156.                     cl_var[i] != '\0')
  157.                      ++i;
  158.                   define_opt(cl_var, i, one_tok); /* define the identifier */
  159.                   cl_var += i;
  160.                   break;
  161.                case 'A':
  162.                   /*
  163.                    * Memory model. Define corresponding identifiers after
  164.                    *  after making sure all others are undefined.
  165.                    */
  166.                   ++cl_var;
  167.                   switch (*cl_var) {
  168.                      case 'S':
  169.                         /*
  170.                          * -AS - small memory model.
  171.                          */
  172.                         do_directive(undef_model);
  173.                         do_directive("#define M_I86SM 1\n");
  174.                         break;
  175.                      case 'C':
  176.                         /*
  177.                          * -AC - compact memory model.
  178.                          */
  179.                         do_directive(undef_model);
  180.                         do_directive("#define M_I86CM 1\n");
  181.                        break;
  182.                      case 'M':
  183.                         /*
  184.                          * -AM - medium memory model.
  185.                          */
  186.                         do_directive(undef_model);
  187.                         do_directive("#define M_I86MM 1\n");
  188.                         break;
  189.                      case 'L':
  190.                         /*
  191.                          * -AL - large memory model.
  192.                          */
  193.                         do_directive(undef_model);
  194.                         do_directive("#define M_I86LM 1\n");
  195.                         break;
  196.                      case 'H':
  197.                         /*
  198.                          * -AH - huge memory model.
  199.                          */
  200.                         do_directive(undef_model);
  201.                         do_directive("#define M_I86LM 1\n");
  202.                         do_directive("#define M_I86HM 1\n");
  203.                         break;
  204.                      }
  205.                   break;
  206.                case 'Z':
  207.                   ++cl_var;
  208.                   if (*cl_var == 'a') {
  209.                      /*
  210.                       * -Za
  211.                       */
  212.                      do_directive("#undef NO_EXT_KEYS\n");
  213.                      do_directive("#define NO_EXT_KEYS 1\n");
  214.                      }
  215.                   break;
  216.                case 'J':
  217.                    do_directive("#undef _CHAR_UNSIGED\n"); 
  218.                    do_directive("#define _CHAR_UNSIGNED 1\n");
  219.                    break;
  220.                }
  221.             }
  222.          if (*cl_var != '\0')
  223.             ++cl_var;
  224.          }
  225. #endif                    /* MICROSOFT */
  226.  
  227. #if TURBO
  228.    char *undef_models = "#undef __TINY__\n#undef __SMALL__\n#undef __MEDIUM__\n\
  229. #undef __COMPACT__\n#undef __LARGE__\n#undef __HUGE__\n";
  230.    char dir_buf[60];
  231.    char *cfg_fname;
  232.    FILE *cfg_file;
  233.    char cbuf[CBufSz];
  234.    int c;
  235.     
  236.    do_directive("#define __MSDOS__ 1\n");
  237.    do_directive("#define __SMALL__ 1\n");
  238.    do_directive("#define __CDECL__ 1\n");
  239.    sprintf(dir_buf, "#define __TURBOC__ %s\n", StrMBody(__TURBOC__));
  240.    do_directive(dir_buf);
  241.     
  242.    /*
  243.     * Process all applicable options from the configuration file.
  244.     */
  245.    cfg_fname = searchpath("turboc.cfg");
  246.    if (cfg_fname != NULL && (cfg_file = fopen(cfg_fname, "r")) != NULL) {
  247.       c = getc(cfg_file);
  248.       while (c != EOF) {
  249.             if (c == '-') {
  250.              c = getc(cfg_file);
  251.              switch (c) {
  252.                 case 'U':
  253.                   /*
  254.                    * Undefine a specific identifier. Locate the identifier's
  255.                    *  end.
  256.                    */
  257.                    i = 0;
  258.                    c = getc(cfg_file);
  259.                    while (c != ' ' && c != '\t' && c != '\n' && c != EOF) {
  260.                       if (i >= CBufSz) {
  261.                          cbuf[CBufSz - 1] = '\0';
  262.                          err2("-U argument too big: ", cbuf);
  263.                          }
  264.                       cbuf[i++] = c;
  265.                       c = getc(cfg_file);
  266.                       }
  267.                    undef_opt(cbuf, i); /* undefine identifier */
  268.                    break;
  269.                 case 'D':
  270.                   /*
  271.                    * Define an identifier. If no defining string is given,
  272.                    *  the definition is empty.
  273.                    */
  274.                    i = 0;
  275.                    c = getc(cfg_file);
  276.                    while (c != ' ' && c != '\t' && c != '\n' && c != EOF) {
  277.                       if (i >= CBufSz) {
  278.                          cbuf[CBufSz - 1] = '\0';
  279.                          err2("-D argument too big: ", cbuf);
  280.                          }
  281.                       cbuf[i++] = c;
  282.                       c = getc(cfg_file);
  283.                       }
  284.                    define_opt(cbuf, i, NULL); /* define the identifier */
  285.                    break;
  286.                 case 'm':
  287.                    /*
  288.                     * Memory model. Define the appropriate macro after
  289.                     *  insuring that all other memory model macros are
  290.                     *  undefined.
  291.                     */
  292.                    switch (c = getc(cfg_file)) {
  293.                       case 't':
  294.                          do_directive(undef_models);
  295.                          do_directive("#define __TINY__ 1\n");
  296.                          break;
  297.                       case 's':
  298.                          do_directive(undef_models);
  299.                          do_directive("#define __SMALL__ 1\n");
  300.                          break;
  301.                       case 'm':
  302.                          do_directive(undef_models);
  303.                          do_directive("#define __MEDIUM__ 1\n");
  304.                          break;
  305.                       case 'c':
  306.                          do_directive(undef_models);
  307.                          do_directive("#define __COMPACT__ 1\n");
  308.                          break;
  309.                       case 'l':
  310.                          do_directive(undef_models);
  311.                          do_directive("#define __LARGE__ 1\n");
  312.                          break;
  313.                       case 'h':
  314.                          do_directive(undef_models);
  315.                          do_directive("#define __HUGE__ 1\n");
  316.                          break;
  317.                       }
  318.                    break;
  319.                 case 'p':
  320.                    do_directive("#undef __PASCAL__\n#undef __CDECL__\n");
  321.                    do_directive("#define __PASCAL__ 1\n");
  322.                    break;
  323.                 }
  324.              }
  325.           if (c != EOF)
  326.              c = getc(cfg_file);
  327.           }
  328.        fclose(cfg_file);
  329.        }
  330. #endif                     /* TURBO */
  331.  
  332. #if HIGHC_386 || INTEL_386 || ZTC_386
  333.    /* something may be needed */
  334. #endif                    /* HIGHC_386 || INTEL_386 || ... */
  335. #endif                    /* MSDOS */
  336.  
  337. #if UNIX
  338.    do_directive("#define unix 1\n");
  339.    do_directive(PPInit);   /* defines that vary between Unix systems */
  340. #endif                    /* UNIX */
  341.  
  342. #if VMS
  343.    /* nothing is needed */
  344. #endif                    /* VMS */
  345.  
  346. /*
  347.  * End of operating-system specific code.
  348.  */
  349.  
  350.    /*
  351.     * look for options that affect macro definitions (-U, -D, etc).
  352.     */
  353.    for (i = 0; opt_lst[i] != '\0'; ++i)
  354.       switch(opt_lst[i]) {
  355.          case 'U':
  356.             /*
  357.              * Undefine and predefined identifier.
  358.              */
  359.             undef_opt(opt_args[i], (int)strlen(opt_args[i]));
  360.             break;
  361.  
  362.          case 'D':
  363.             /*
  364.              * Define an identifier. Use "1" if no defining string is given.
  365.              */
  366.             define_opt(opt_args[i], (int)strlen(opt_args[i]), one_tok);
  367.             break;
  368.  
  369. /*
  370.  * The following code is operating-system dependent [@p_init.03]. Check for
  371.  *  system specific options from command line.
  372.  */
  373.  
  374. #if PORT
  375.    /* something may be needed */
  376. Deliberate Syntax Error
  377. #endif                    /* PORT */
  378.  
  379. #if AMIGA || ATARI_ST || MACINTOSH || VM || MVS
  380.    /* something may be needed */
  381. Deliberate Syntax Error
  382. #endif                    /* AMIGA || ATARI_ST || ... */
  383.  
  384. #if MSDOS
  385. #if MICROSOFT
  386.          case 'A':
  387.             /*
  388.              * Memory model. Define corresponding identifiers after
  389.              *  after making sure all others are undefined.
  390.              */
  391.             switch (*opt_args[i]) {
  392.                case 'S':
  393.                   /*
  394.                    * -AS - small memory model.
  395.                    */
  396.                   do_directive(undef_model);
  397.                   do_directive("#define M_I86SM 1\n");
  398.                   break;
  399.                case 'C':
  400.                   /*
  401.                    * -AC - compact memory model.
  402.                    */
  403.                   do_directive(undef_model);
  404.                   do_directive("#define M_I86CM 1\n");
  405.                   break;
  406.                case 'M':
  407.                   /*
  408.                    * -AM - medium memory model.
  409.                    */
  410.                   do_directive(undef_model);
  411.                   do_directive("#define M_I86MM 1\n");
  412.                   break;
  413.                case 'L':
  414.                   /*
  415.                    * -AL - large memory model.
  416.                    */
  417.                   do_directive(undef_model);
  418.                   do_directive("#define M_I86LM 1\n");
  419.                   break;
  420.                case 'H':
  421.                   /*
  422.                    * -AH - huge memory model.
  423.                    */
  424.                   do_directive(undef_model);
  425.                   do_directive("#define M_I86LM 1\n");
  426.                   do_directive("#define M_I86HM 1\n");
  427.                   break;
  428.                default:
  429.                   fprintf(stderr, "invalid argument to -A option: %s\n",
  430.                      opt_args[i]);
  431.                   show_usage();
  432.                }
  433.             break;
  434.          case 'Z':
  435.             if (*opt_args[i] == 'a') {
  436.                do_directive("#undef NO_EXT_KEYS\n");
  437.                do_directive("#define NO_EXT_KEYS 1\n");
  438.                }
  439.             else {
  440.                fprintf(stderr, "invalid argument to -Z option: %s\n",
  441.                   opt_args[i]);
  442.                show_usage();
  443.             }
  444.             break;
  445.          case 'J':
  446.              do_directive("#undef _CHAR_UNSIGED\n"); 
  447.              do_directive("#define _CHAR_UNSIGNED 1\n");
  448.              break;
  449. #endif                    /* MICROSOFT */
  450.  
  451. #if TURBO
  452.          case 'm':
  453.             /*
  454.              * Memory model. Define the appropriate macro after
  455.              *  insuring that all other memory model macros are
  456.              *  undefined.
  457.              */
  458.             switch (*opt_args[i]) {
  459.                case 't':
  460.                   do_directive(undef_models);
  461.                   do_directive("#define __TINY__ 1\n");
  462.                   break;
  463.                case 's':
  464.                   do_directive(undef_models);
  465.                   do_directive("#define __SMALL__ 1\n");
  466.                   break;
  467.                case 'm':
  468.                   do_directive(undef_models);
  469.                   do_directive("#define __MEDIUM__ 1\n");
  470.                   break;
  471.                case 'c':
  472.                   do_directive(undef_models);
  473.                   do_directive("#define __COMPACT__ 1\n");
  474.                   break;
  475.                case 'l':
  476.                   do_directive(undef_models);
  477.                   do_directive("#define __LARGE__ 1\n");
  478.                   break;
  479.                case 'h':
  480.                   do_directive(undef_models);
  481.                   do_directive("#define __HUGE__ 1\n");
  482.                   break;
  483.                default:
  484.                   fprintf(stderr, "invalid argument to -m option: %s\n",
  485.                      opt_args[i]);
  486.                   show_usage();
  487.                }
  488.             break;
  489.          case 'p':
  490.             do_directive("#undef __PASCAL__\n#undef __CDECL__\n");
  491.             do_directive("#define __PASCAL__ 1\n");
  492.             break;
  493. #endif                    /* TURBO */
  494.  
  495. #if HIGHC_386 || INTEL_386 || ZTC_386
  496.    /* something may be needed */
  497. #endif                    /* HIGHC_386 || INTEL_386 || ZTC_386 */
  498. #endif                    /* MSDOS */
  499.  
  500. #if UNIX || VMS
  501.    /* nothing is needed */
  502. #endif                    /* UNIX || VMS */
  503.  
  504. /*
  505.  * End of operating-system specific code.
  506.  */
  507.          }
  508.    }
  509.  
  510. /*
  511.  * str_src - establish a string, given by a character pointer and a length,
  512.  *  as the current source of tokens.
  513.  */
  514. novalue str_src(src_name, s, len)
  515. char *src_name;
  516. char *s;
  517. int len;
  518.    {
  519.    union src_ref ref;
  520.    int *ip1, *ip2;
  521.  
  522.    /*
  523.     * Create a character source with a large enought buffer for the string.
  524.     */
  525.    ref.cs = new_cs(src_name, NULL, len + 1);
  526.    push_src(CharSrc, &ref);
  527.    ip1 = ref.cs->char_buf;
  528.    ip2 = ref.cs->line_buf;
  529.    while (len-- > 0) {
  530.      *ip1++ = *s++;    /* copy string to source buffer */
  531.      *ip2++ = 0;       /* characters are from "line 0" */
  532.      }
  533.    *ip1 = EOF;
  534.    *ip2 = 0;
  535.    ref.cs->next_char = ref.cs->char_buf;
  536.    ref.cs->last_char = ip1;
  537.    first_char = ref.cs->char_buf;
  538.    next_char = first_char;
  539.    last_char = ref.cs->last_char;
  540.    }
  541.  
  542. /*
  543.  * do_directive - take a character string containing preprocessor
  544.  *  directives separated by new-lines and execute them. This done
  545.  *  by preprocessing the string.
  546.  */
  547. static novalue do_directive(s)
  548. char *s;
  549.    {
  550.    str_src("<initialization>", s, (int)strlen(s));
  551.    while (interp_dir() != NULL)
  552.       ;
  553.    }
  554.    
  555. /*
  556.  * undef_opt - take the argument to a -U option and, if it is valid,
  557.  *  undefine it.
  558.  */
  559. static novalue undef_opt(s, len)
  560. char *s;
  561. int len;
  562.    {
  563.    struct token *mname;
  564.    int i;
  565.  
  566.    /*
  567.     * The name is needed in the form of a token. Use the preprocessor
  568.     *  to tokenize it.
  569.     */
  570.    str_src("<options>", s, len);
  571.    mname = next_tok();
  572.    if (mname == NULL || mname->tok_id != Identifier ||
  573.      next_tok() != NULL) {
  574.       fprintf(stderr, "invalid argument to -U option: ");
  575.       for (i = 0; i < len; ++i)
  576.          putc(s[i], stderr);    /* show offending argument */
  577.       putc('\n', stderr);
  578.       show_usage();
  579.       }
  580.    m_delete(mname);
  581.    }
  582.  
  583. /*
  584.  * define_opt - take an argument to a -D option and, if it is valid, perform
  585.  *  the requested definition.
  586.  */
  587. static novalue define_opt(s, len, dflt)
  588. char *s;
  589. int len;
  590. struct token *dflt;
  591.    {
  592.    struct token *mname;
  593.    struct token *t;
  594.    struct tok_lst *body;
  595.    struct tok_lst **ptlst, **trail_whsp;
  596.    int i;
  597.  
  598.    /*
  599.     * The argument to -D must be tokenized.
  600.     */
  601.    str_src("<options>", s, len);
  602.  
  603.    /*
  604.     * Find the macro name.
  605.     */
  606.    mname = next_tok();
  607.    if (mname == NULL || mname->tok_id != Identifier) {
  608.       fprintf(stderr, "invalid argument to -D option: ");
  609.       for (i = 0; i < len; ++i)
  610.          putc(s[i], stderr);
  611.       putc('\n', stderr);
  612.       show_usage();
  613.       }
  614.  
  615.    /*
  616.     * Determine if the name is followed by '='.
  617.     */
  618.    if (chk_eq_sign()) {
  619.       /*
  620.        * Macro body is given, strip leading white space
  621.        */
  622.       t = next_tok();
  623.       if (t != NULL && t->tok_id == WhiteSpace) {
  624.          free_t(t);
  625.          t = next_tok();
  626.          }
  627.             
  628.  
  629.       /*
  630.        * Construct the token list for body of macro. Keep track of trailing
  631.        *  white space so it can be deleted.
  632.        */
  633.       body = NULL;
  634.       ptlst = &body;
  635.       trail_whsp = NULL;
  636.       while (t != NULL) {
  637.          t->flag &= ~LineChk;
  638.          (*ptlst) = new_t_lst(t);
  639.          if (t->tok_id == WhiteSpace)
  640.             trail_whsp = ptlst;
  641.          else
  642.             trail_whsp = NULL;
  643.          ptlst = &(*ptlst)->next;
  644.          t = next_tok();
  645.          }
  646.      
  647.       /*
  648.        * strip trailing white space
  649.        */
  650.       if (trail_whsp != NULL) {
  651.          free_t_lst(*trail_whsp);
  652.          *trail_whsp = NULL;
  653.          }
  654.       }
  655.    else {
  656.       /* 
  657.        * There is no '=' after the macro name; use the supplied
  658.        *  default value for the macro definition.
  659.        */
  660.       if (next_tok() == NULL)
  661.          if (dflt == NULL)
  662.             body = NULL;
  663.          else
  664.             body = new_t_lst(copy_t(dflt));
  665.       else {
  666.          fprintf(stderr, "invalid argument to -D option: ");
  667.          for (i = 0; i < len; ++i)
  668.             putc(s[i], stderr);
  669.          putc('\n', stderr);
  670.          show_usage();
  671.          }
  672.       }
  673.  
  674.    m_install(mname, NoArgs, 0, NULL, body); /* install macro definition */
  675.    }
  676.